const { imfix } = require('@/api/env.js')

const CryptoJS = require('./crypto-js.min');
const b64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
const b64re = /^(?:[A-Za-z\d+\/]{4})*?(?:[A-Za-z\d+\/]{2}(?:==)?|[A-Za-z\d+\/]{3}=?)?$/;
export let prefix = imfix//默认环境前缀，登录用户id，群组id,前缀配置
// #ifdef MP-WEIXIN
const { miniProgram } = uni.getAccountInfoSync()
if (miniProgram.envVersion !== 'release') prefix = imfix + 'T'  //微信体验版（trial），开发版环境（develop）
// #endif
// #ifdef APP-PLUS
if (process.env.NODE_ENV === 'development') prefix = imfix + 'T' //测试环境
// #endif
uni.$prefix = prefix
export const avatarPrefix = 'https://storage.zego.im/zim/example/web/assets/';
export const appConfig = {
	appID: 376023297, // AppID - type: number
	appSign: '29d535122d967abb4d21a82d4bd1efe0c31e62ed52a9463c3c1153a8c0a8ac67', // AppSign - type: 64 byte length string (only used in native platform)
	serverSecret: '9c746b2d7388b610b43abae4fcf14c1d', // ServerSecret - type: 32 byte length string
};

// only for develop test
// #ifdef H5
if (window && window.location.search) {
	const params = new URLSearchParams(window.location.search);
	const appID = Number(params.get('a'));
	const serverSecret = params.get('s');
	Object.assign(appConfig, { appID, serverSecret });
	console.log('appConfig', JSON.stringify(appConfig));
}
// #endif

export function generateToken(userID, seconds) {
	if (!userID) throw new Error('generateToken error: params invalid.');

	var time = (Date.now() / 1000) | 0;
	var body = {
		app_id: Number(appConfig.appID),
		user_id: String(userID),
		nonce: (Math.random() * 2147483647) | 0,
		ctime: time,
		expire: time + Number(seconds || 7200),
	};

	var key = CryptoJS.enc.Utf8.parse(appConfig.serverSecret);
	var iv = Math.random().toString().substring(2, 18);
	if (iv.length < 16) iv += iv.substring(0, 16 - iv.length);

	var ciphertext = CryptoJS.AES.encrypt(JSON.stringify(body), key, { iv: CryptoJS.enc.Utf8.parse(iv) }).toString();
	var ciphert = Uint8Array.from(Array.from(weAtob(ciphertext)).map((val) => val.charCodeAt(0)));
	var len_ciphert = ciphert.length;

	var uint8 = new Uint8Array(8 + 2 + 16 + 2 + len_ciphert);
	// expire: 8
	uint8.set([0, 0, 0, 0]);
	uint8.set(new Uint8Array(Int32Array.from([body.expire]).buffer).reverse(), 4);
	// iv length: 2
	uint8[8] = 16 >> 8;
	uint8[9] = 16 - (uint8[8] << 8);
	// iv: 16
	uint8.set(Uint8Array.from(Array.from(iv).map((val) => val.charCodeAt(0))), 10);

	uint8[26] = len_ciphert >> 8;
	uint8[27] = len_ciphert - (uint8[26] << 8);

	uint8.set(ciphert, 28);

	var token = `04${weBtoa(String.fromCharCode(...Array.from(uint8)))}`;

	return token;
}

// btoa
const weBtoa = function(string) {
	string = String(string);
	var bitmap,
		a,
		b,
		c,
		result = '',
		i = 0,
		rest = string.length % 3;

	for (; i < string.length;) {
		if (
			(a = string.charCodeAt(i++)) > 255 ||
			(b = string.charCodeAt(i++)) > 255 ||
			(c = string.charCodeAt(i++)) > 255
		)
			throw new TypeError(
				"Failed to execute 'btoa' on 'Window': The string to be encoded contains characters outside of the Latin1 range.",
			);

		bitmap = (a << 16) | (b << 8) | c;
		result +=
			b64.charAt((bitmap >> 18) & 63) +
			b64.charAt((bitmap >> 12) & 63) +
			b64.charAt((bitmap >> 6) & 63) +
			b64.charAt(bitmap & 63);
	}

	return rest ? result.slice(0, rest - 3) + '==='.substring(rest) : result;
};
// atob
const weAtob = function(string) {
	string = String(string).replace(/[\t\n\f\r ]+/g, '');
	if (!b64re.test(string))
		throw new TypeError("Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded.");
	string += '=='.slice(2 - (string.length & 3));
	var bitmap,
		result = '',
		r1,
		r2,
		i = 0;
	for (; i < string.length;) {
		bitmap =
			(b64.indexOf(string.charAt(i++)) << 18) |
			(b64.indexOf(string.charAt(i++)) << 12) |
			((r1 = b64.indexOf(string.charAt(i++))) << 6) |
			(r2 = b64.indexOf(string.charAt(i++)));

		result +=
			r1 === 64 ?
			String.fromCharCode((bitmap >> 16) & 255) :
			r2 === 64 ?
			String.fromCharCode((bitmap >> 16) & 255, (bitmap >> 8) & 255) :
			String.fromCharCode((bitmap >> 16) & 255, (bitmap >> 8) & 255, bitmap & 255);
	}
	return result;
};